﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FATCATool
{
    public partial class FATCATree : UserControl
    {
        public event TreeNodeSelectedEventHandler TreeNodeSelected;
        private FATCA_OECD _filing;
        private TreeNode _clickedNode;

        public FATCATree()
        {
            InitializeComponent();
        }

        protected virtual void OnTreeNodeSelected(NodeSelectedEventArgs e)
        {
            if (TreeNodeSelected != null && (treeNav.SelectedNode != null))
                TreeNodeSelected(this, e);
        }

        public void LoadTree(FATCA_OECD filing)
        {
            treeNav.Nodes.Clear();

            _filing = filing;
            var tree = _filing.GetTree();

            var treeNode = new TreeNode() { Text = tree.Name, Tag = tree };
            treeNav.Nodes.Add(treeNode);

            LoadNodes(treeNode);
        }

        private void LoadNodes(TreeNode treeNode)
        {
            var node = (FATCASchema.Nodes.iNode)treeNode.Tag;

            if (node.Children != null)
            {
                foreach (var child in node.Children)
                {
                    var childTreeNode = new TreeNode() { Text = child.Name, Tag = child };
                    treeNode.Nodes.Add(childTreeNode);

                    LoadNodes(childTreeNode);
                }
            }
        }

        private void treeNav_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (treeNav.SelectedNode == null || !(treeNav.SelectedNode.Tag is FATCASchema.Nodes.iNode))
                return;

            this.OnTreeNodeSelected(new NodeSelectedEventArgs(_filing, (FATCASchema.Nodes.iNode)treeNav.SelectedNode.Tag, e.Node));
        }

        private void treeNav_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                var point = new Point(e.X, e.Y);
                _clickedNode = treeNav.GetNodeAt(point);
                if (_clickedNode.Tag is FATCASchema.Nodes.ReportingGroupNode)
                {
                    foreach (TreeNode n in _clickedNode.Nodes)
                    {
                        if (n.Text == "Sponsor")
                            mnuReportingGroup.Items[mnuReportingGroup.Items.IndexOf(mnuSponsor)].Visible = false;
                        if (n.Text == "Intermediary")
                            mnuReportingGroup.Items[mnuReportingGroup.Items.IndexOf(mnuAddIntermediary)].Visible = false;
                    }
                    mnuReportingGroup.Show(treeNav, point);
                }
                else if (_clickedNode.Tag is FATCASchema.Nodes.AccountReportNode
                    || _clickedNode.Tag is FATCASchema.Nodes.PoolReportNode
                    || _clickedNode.Tag is FATCASchema.Nodes.FATCANode
                    || (_clickedNode.Tag is FATCASchema.Nodes.CorrectableOrganisationParty && _clickedNode.Name == "Sponsor")
                    || (_clickedNode.Tag is FATCASchema.Nodes.CorrectableOrganisationParty && _clickedNode.Name == "Intermediary"))
                {
                    mnuGeneral.Show(treeNav, point);
                }
                else if (_clickedNode.Tag is FATCASchema.Nodes.FATCA_OECDNode)
                {
                    mnuRoot.Show(treeNav, point);
                }
            }
        }

        private void mnuAddAccount_Click(object sender, EventArgs e)
        {
            if (_clickedNode == null || !(_clickedNode.Tag is FATCASchema.Nodes.ReportingGroupNode))
                return;

            var rg = (FATCASchema.Nodes.ReportingGroupNode)_clickedNode.Tag;
            var account = rg.AddAccountReport();
            _clickedNode.Nodes.Add(new TreeNode() { Text = account.Name, Tag = account });
        }

        private void mnuAddPool_Click(object sender, EventArgs e)
        {
            if (_clickedNode == null || !(_clickedNode.Tag is FATCASchema.Nodes.ReportingGroupNode))
                return;

            var rg = (FATCASchema.Nodes.ReportingGroupNode)_clickedNode.Tag;
            var pool = rg.AddPoolReport();
            _clickedNode.Nodes.Add(new TreeNode() { Text = pool.Name, Tag = pool });
        }

        private void mnuAddIntermediary_Click(object sender, EventArgs e)
        {
            if (_clickedNode == null || !(_clickedNode.Tag is FATCASchema.Nodes.ReportingGroupNode))
                return;

            var rg = (FATCASchema.Nodes.ReportingGroupNode)_clickedNode.Tag;
            var intermediary = rg.AddIntermediary();
            _clickedNode.Nodes.Add(new TreeNode() { Text = intermediary.Name, Tag = intermediary });
        }

        private void mnuSponsor_Click(object sender, EventArgs e)
        {
            if (_clickedNode == null || !(_clickedNode.Tag is FATCASchema.Nodes.ReportingGroupNode))
                return;

            var rg = (FATCASchema.Nodes.ReportingGroupNode)_clickedNode.Tag;
            var sponsor = rg.AddSponsor();
            _clickedNode.Nodes.Add(new TreeNode() { Text = sponsor.Name, Tag = sponsor });
        }

        void mnuAddFatca_Click(object sender, System.EventArgs e)
        {
            if (_clickedNode == null || !(_clickedNode.Tag is FATCASchema.Nodes.FATCA_OECDNode))
                return;

            var root = (FATCASchema.Nodes.FATCA_OECDNode)_clickedNode.Tag;
            var fatca = root.AddFATCA();

            var newTreeNode = new TreeNode() { Text = fatca.Name, Tag = fatca };
            _clickedNode.Nodes.Add(newTreeNode);
            LoadNodes(newTreeNode);
        }

        private void mnuDelete_Click(object sender, EventArgs e)
        {
            if (_clickedNode == null)
                return;

            if (_clickedNode.Parent.Tag is FATCASchema.Nodes.ReportingGroupNode)
            {
                var rgNode = (FATCASchema.Nodes.ReportingGroupNode)_clickedNode.Parent.Tag;

                if (!(rgNode.NodeObject is Fatca_TypeReportingGroup))
                    return;

                var rgObject = (Fatca_TypeReportingGroup)rgNode.NodeObject;


                if (_clickedNode.Name == "Sponsor" && _clickedNode.Tag is FATCASchema.Nodes.CorrectableOrganisationParty)
                {
                    _clickedNode.Parent.Nodes.Remove(_clickedNode);
                    rgObject.Sponsor = null;
                }
                else if (_clickedNode.Name == "Intermediary" && _clickedNode.Tag is FATCASchema.Nodes.CorrectableOrganisationParty)
                {
                    _clickedNode.Parent.Nodes.Remove(_clickedNode);
                    rgObject.Intermediary = null;
                }
                else if (_clickedNode.Tag is FATCASchema.Nodes.AccountReportNode)
                {
                    _clickedNode.Parent.Nodes.Remove(_clickedNode);
                    var acctList = rgObject.AccountReport.ToList();
                    var acctNode = (FATCASchema.Nodes.AccountReportNode)_clickedNode.Tag;
                    acctList.Remove((CorrectableAccountReport_Type)acctNode.NodeObject);
                    rgObject.AccountReport = acctList.ToArray();
                }
                else if (_clickedNode.Tag is FATCASchema.Nodes.PoolReportNode)
                {
                    _clickedNode.Parent.Nodes.Remove(_clickedNode);
                    var acctList = rgObject.PoolReport.ToList();
                    var acctNode = (FATCASchema.Nodes.PoolReportNode)_clickedNode.Tag;
                    acctList.Remove((CorrectablePoolReport_Type)acctNode.NodeObject);
                    rgObject.PoolReport = acctList.ToArray();
                }
            }
            else if (_clickedNode.Parent.Tag is FATCASchema.Nodes.FATCA_OECDNode)
            {
                var rootNode = (FATCASchema.Nodes.FATCA_OECDNode)_clickedNode.Parent.Tag;

                if (!(rootNode.NodeObject is FATCA_OECD))
                    return;

                var rootObject = (FATCA_OECD)rootNode.NodeObject;
                _clickedNode.Parent.Nodes.Remove(_clickedNode);
                var fatcaList = rootObject.FATCA.ToList();
                var fatcaNode = (FATCASchema.Nodes.FATCANode)_clickedNode.Tag;

                fatcaList.Remove((Fatca_Type)fatcaNode.NodeObject);
                rootObject.FATCA = fatcaList.ToArray();
            }
        }
    }

    public delegate void TreeNodeSelectedEventHandler(object sender, NodeSelectedEventArgs e);

    public class NodeSelectedEventArgs : EventArgs
    {
        public NodeSelectedEventArgs(FATCA_OECD filing, FATCASchema.Nodes.iNode node, TreeNode treeNode)
        {
            this.Filing = filing;
            this.Node = node;
            this.TNode = treeNode;
        }

        public FATCA_OECD Filing = null;
        public FATCASchema.Nodes.iNode Node = null;
        public TreeNode TNode = null;
    }
}
